{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "0c423ad0-dbba-4155-a9a1-ce8a13bb9930",
   "metadata": {},
   "source": [
    "# 分组与聚合操作\n",
    "\n",
    "在Excel中，我们经常使用\"分类汇总\"和\"数据透视表\"来实现分组统计。Pandas的groupby提供了更强大的分组功能，让我们可以进行更复杂的分析。\n",
    "\n",
    "## 基础分组操作"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "7fe172e8-f1d5-4a24-a3b8-22d51bec0c7f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 导入所需的库\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "# 读取数据\n",
    "df_students = pd.read_csv('data/student_info.csv')\n",
    "df_orders = pd.read_csv('data/order_info.csv')\n",
    "df_products = pd.read_csv('data/product_info.csv')\n",
    "df_order_details = pd.read_csv('data/order_details.csv')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ebaccca3-8da9-439a-b729-ffdd5600c04e",
   "metadata": {},
   "source": [
    "## 基础分组操作\n",
    "\n",
    "### 1. 单字段分组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "cc153506-6d03-42b3-8903-cc3939ace0cb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "基本分组统计（按商品类别汇总销售额）：\n",
      "商品类别\n",
      "图书       111399.04\n",
      "学习用品      38804.78\n",
      "服装       242474.24\n",
      "生活用品     139853.65\n",
      "电子产品    2986024.71\n",
      "运动器材     351649.84\n",
      "食品        62320.16\n",
      "Name: 订单金额, dtype: float64\n",
      "\n",
      "分组信息：\n",
      "分组数量: 7\n",
      "分组项: ['图书', '学习用品', '服装', '生活用品', '电子产品', '运动器材', '食品']\n",
      "\n",
      "各类别订单金额描述性统计：\n",
      "      count         mean          std     min        25%       50%        75%  \\\n",
      "商品类别                                                                            \n",
      "图书    448.0   248.658571   168.770425   20.50   110.9500   201.015    366.090   \n",
      "学习用品  453.0    85.661766    57.940069    6.11    37.6500    73.140    120.400   \n",
      "服装    474.0   511.549030   358.580881   35.85   225.4200   409.695    760.575   \n",
      "生活用品  416.0   336.186659   228.130880   20.25   147.2075   293.825    462.960   \n",
      "电子产品  403.0  7409.490596  5687.776020  132.48  2830.3150  6237.680  10177.450   \n",
      "运动器材  427.0   823.535925   566.752303   50.45   350.8400   688.200   1244.845   \n",
      "食品    407.0   153.120786   112.010836   10.40    66.4250   123.480    213.330   \n",
      "\n",
      "           max  \n",
      "商品类别            \n",
      "图书      742.85  \n",
      "学习用品    246.95  \n",
      "服装     1498.80  \n",
      "生活用品    994.30  \n",
      "电子产品  24901.15  \n",
      "运动器材   2465.80  \n",
      "食品      498.50  \n"
     ]
    }
   ],
   "source": [
    "# 最基本的分组操作，类似于Excel中的分类汇总\n",
    "# 按'商品类别'分组，统计每个类别的订单金额总和\n",
    "basic_group = df_orders.groupby('商品类别')['订单金额'].sum()\n",
    "print(\"基本分组统计（按商品类别汇总销售额）：\")  # 输出基本分组统计的标题\n",
    "print(basic_group)  # 打印每个商品类别的总销售额\n",
    "\n",
    "# 查看分组的基本信息\n",
    "print(\"\\n分组信息：\")  # 输出分组信息的标题\n",
    "group_info = df_orders.groupby('商品类别')  # 创建一个按'商品类别'分组的对象\n",
    "print(f\"分组数量: {len(group_info)}\")  # 打印分组数量\n",
    "print(f\"分组项: {list(group_info.groups.keys())}\")  # 打印分组项的名称列表\n",
    "\n",
    "# 分组后的描述性统计，类似于Excel中的描述统计功能\n",
    "group_desc = df_orders.groupby('商品类别')['订单金额'].describe()\n",
    "print(\"\\n各类别订单金额描述性统计：\")  # 输出描述性统计的标题\n",
    "print(group_desc)  # 打印每个商品类别的订单金额的描述性统计信息\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d19826f3-ca57-47de-8ad7-68d52c3bf71f",
   "metadata": {},
   "source": [
    "多字段分组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "1fc9f938-8e9f-4a4d-805a-c9d487811d54",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "多字段分组统计：\n",
      "         订单数        总金额     平均金额\n",
      "商品类别 年级                         \n",
      "图书   大一  119   28058.13   235.78\n",
      "     大三  105   25424.55   242.14\n",
      "     大二   91   24642.82   270.80\n",
      "     大四  133   33273.54   250.18\n",
      "学习用品 大一  103    8780.44    85.25\n",
      "     大三  130   11104.98    85.42\n",
      "     大二  101    8023.15    79.44\n",
      "     大四  119   10896.21    91.56\n",
      "服装   大一  115   57876.08   503.27\n",
      "     大三  116   62729.98   540.78\n",
      "     大二   96   48709.63   507.39\n",
      "     大四  147   73158.55   497.68\n",
      "生活用品 大一   93   31246.15   335.98\n",
      "     大三   92   29014.61   315.38\n",
      "     大二   92   30295.76   329.30\n",
      "     大四  139   49297.13   354.66\n",
      "电子产品 大一   96  790696.65  8236.42\n",
      "     大三   95  673539.79  7089.89\n",
      "     大二   86  598537.27  6959.74\n",
      "     大四  126  923251.00  7327.39\n",
      "运动器材 大一  100   79125.40   791.25\n",
      "     大三   95   79679.66   838.73\n",
      "     大二  105   94028.11   895.51\n",
      "     大四  127   98816.67   778.08\n",
      "食品   大一  108   15844.35   146.71\n",
      "     大三   94   15025.19   159.84\n",
      "     大二   94   14793.78   157.38\n",
      "     大四  111   16656.84   150.06\n",
      "\n",
      "多字段多指标统计：\n",
      "              订单金额          购买数量      优惠金额        \n",
      "               sum     mean  sum       sum    mean\n",
      "商品类别 年级                                           \n",
      "图书   大一   28058.13   235.78  333   1453.76   12.22\n",
      "     大三   25424.55   242.14  320    998.87    9.51\n",
      "     大二   24642.82   270.80  274   1176.32   12.93\n",
      "     大四   33273.54   250.18  393   1526.04   11.47\n",
      "学习用品 大一    8780.44    85.25  316    500.31    4.86\n",
      "     大三   11104.98    85.42  416    661.71    5.09\n",
      "     大二    8023.15    79.44  295    472.15    4.67\n",
      "     大四   10896.21    91.56  362    622.22    5.23\n",
      "服装   大一   57876.08   503.27  346   3254.95   28.30\n",
      "     大三   62729.98   540.78  369   3214.55   27.71\n",
      "     大二   48709.63   507.39  275   2773.82   28.89\n",
      "     大四   73158.55   497.68  445   4556.99   31.00\n",
      "生活用品 大一   31246.15   335.98  286   1799.61   19.35\n",
      "     大三   29014.61   315.38  269   1661.05   18.05\n",
      "     大二   30295.76   329.30  289   1460.16   15.87\n",
      "     大四   49297.13   354.66  451   2430.41   17.48\n",
      "电子产品 大一  790696.65  8236.42  278  37529.62  390.93\n",
      "     大三  673539.79  7089.89  286  23691.77  249.39\n",
      "     大二  598537.27  6959.74  247  29889.05  347.55\n",
      "     大四  923251.00  7327.39  393  57781.67  458.58\n",
      "运动器材 大一   79125.40   791.25  285   4139.48   41.39\n",
      "     大三   79679.66   838.73  297   3734.69   39.31\n",
      "     大二   94028.11   895.51  333   4421.99   42.11\n",
      "     大四   98816.67   778.08  358   6129.18   48.26\n",
      "食品   大一   15844.35   146.71  301    982.12    9.09\n",
      "     大三   15025.19   159.84  284    676.55    7.20\n",
      "     大二   14793.78   157.38  289    733.38    7.80\n",
      "     大四   16656.84   150.06  316    715.12    6.44\n"
     ]
    }
   ],
   "source": [
    "# 按多个字段分组，类似于Excel中的多级分类汇总\n",
    "multi_group = df_orders.groupby(['商品类别', '年级'])['订单金额'].agg([\n",
    "    ('订单数', 'count'),  # 计算每个分组的订单数量\n",
    "    ('总金额', 'sum'),    # 计算每个分组的订单金额总和\n",
    "    ('平均金额', 'mean')  # 计算每个分组的订单金额平均值\n",
    "]).round(2)  # 将结果四舍五入到小数点后两位\n",
    "\n",
    "print(\"多字段分组统计：\")  # 输出多字段分组统计的标题\n",
    "print(multi_group)  # 打印多字段分组统计的结果\n",
    "\n",
    "# 按多个字段分组，对不同的列应用不同的聚合函数进行统计分析\n",
    "multi_stats = df_orders.groupby(['商品类别', '年级']).agg({\n",
    "    '订单金额': ['sum', 'mean'],  # 对'订单金额'列进行求和和求平均\n",
    "    '购买数量': 'sum',            # 对'购买数量'列进行求和\n",
    "    '优惠金额': ['sum', 'mean']   # 对'优惠金额'列进行求和和求平均\n",
    "}).round(2)  # 将结果四舍五入到小数点后两位\n",
    "\n",
    "print(\"\\n多字段多指标统计：\")  # 输出多字段多指标统计的标题\n",
    "print(multi_stats)  # 打印多字段多指标统计的结果\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5c0b6936-cce4-4dc5-8685-09c9b4de3a31",
   "metadata": {},
   "source": [
    "分组统计（agg）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "4a959b44-e0ed-4b9f-8ce3-20f2db750fc2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "复杂分组统计：\n",
      "            订单金额                                  购买数量      \n",
      "            总销售额    平均订单额  订单数      最大订单    最小订单   总数量  平均数量\n",
      "商品类别                                                        \n",
      "图书     111399.04   248.66  448    742.85   20.50  1320  2.95\n",
      "学习用品    38804.78    85.66  453    246.95    6.11  1389  3.07\n",
      "服装     242474.24   511.55  474   1498.80   35.85  1435  3.03\n",
      "生活用品   139853.65   336.19  416    994.30   20.25  1295  3.11\n",
      "电子产品  2986024.71  7409.49  403  24901.15  132.48  1204  2.99\n",
      "运动器材   351649.84   823.54  427   2465.80   50.45  1273  2.98\n",
      "食品      62320.16   153.12  407    498.50   10.40  1190  2.92\n"
     ]
    }
   ],
   "source": [
    "# 使用 agg 方法进行复杂的分组统计\n",
    "advanced_stats = df_orders.groupby('商品类别').agg({\n",
    "    '订单金额': [  # 对 '订单金额' 列进行多种统计\n",
    "        ('总销售额', 'sum'),  # 计算每个商品类别的订单金额总和，并重命名为 \"总销售额\"\n",
    "        ('平均订单额', 'mean'),  # 计算每个商品类别的平均订单金额，并重命名为 \"平均订单额\"\n",
    "        ('订单数', 'count'),  # 计算每个商品类别的订单数量，并重命名为 \"订单数\"\n",
    "        ('最大订单', 'max'),  # 计算每个商品类别的最大订单金额，并重命名为 \"最大订单\"\n",
    "        ('最小订单', 'min')  # 计算每个商品类别的最小订单金额，并重命名为 \"最小订单\"\n",
    "    ],\n",
    "    '购买数量': [  # 对 '购买数量' 列进行统计\n",
    "        ('总数量', 'sum'),  # 计算每个商品类别的购买数量总和，并重命名为 \"总数量\"\n",
    "        ('平均数量', 'mean')  # 计算每个商品类别的平均购买数量，并重命名为 \"平均数量\"\n",
    "    ]\n",
    "}).round(2)  # 将结果四舍五入到小数点后两位\n",
    "\n",
    "print(\"复杂分组统计：\")  # 输出复杂分组统计的标题\n",
    "print(advanced_stats)  # 打印复杂分组统计的结果\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2b65ada6-8567-4263-9889-1c4a26404875",
   "metadata": {},
   "source": [
    "分组转换（transform）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "0aa8475c-d565-4d63-82e1-c6209a6aa135",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "分组转换结果示例：\n",
      "   商品类别     订单金额      类别总金额   占类别比例      类别平均金额  与平均值差异\n",
      "0  运动器材  1102.11  351649.84  0.0031  823.535925  278.57\n",
      "1    食品    88.35   62320.16  0.0014  153.120786  -64.77\n",
      "2  生活用品   108.48  139853.65  0.0008  336.186659 -227.71\n",
      "3    图书    79.72  111399.04  0.0007  248.658571 -168.94\n",
      "4  生活用品   404.97  139853.65  0.0029  336.186659   68.78\n"
     ]
    }
   ],
   "source": [
    "# 使用 transform 方法进行组内计算（在 Excel 中需要用复杂的公式实现）\n",
    "# 计算每个订单金额在所属商品类别总金额中所占的比例\n",
    "df_orders['类别总金额'] = df_orders.groupby('商品类别')['订单金额'].transform('sum')  \n",
    "# 对 '商品类别' 分组，计算每个类别的订单金额总和，并将结果分配到每个订单中\n",
    "\n",
    "df_orders['占类别比例'] = (df_orders['订单金额'] / df_orders['类别总金额']).round(4)  \n",
    "# 计算每个订单金额占该类别总金额的比例，并将结果保留到小数点后四位\n",
    "\n",
    "# 计算每个订单金额与其类别的平均金额之间的差异\n",
    "df_orders['类别平均金额'] = df_orders.groupby('商品类别')['订单金额'].transform('mean')  \n",
    "# 对 '商品类别' 分组，计算每个类别的订单金额平均值，并将结果分配到每个订单中\n",
    "\n",
    "df_orders['与平均值差异'] = (df_orders['订单金额'] - df_orders['类别平均金额']).round(2)  \n",
    "# 计算每个订单金额与类别平均金额的差异，并将结果保留到小数点后两位\n",
    "\n",
    "print(\"分组转换结果示例：\")  \n",
    "# 输出分组转换结果示例的标题\n",
    "\n",
    "print(df_orders[['商品类别', '订单金额', '类别总金额', '占类别比例', '类别平均金额', '与平均值差异']].head())  \n",
    "# 打印数据框中选定的列，展示前几行的分组转换结果"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ca0e6f62-eebf-49a1-8f49-71b50908264d",
   "metadata": {},
   "source": [
    "### 高级分组操作\n",
    "\n",
    "#### 1. 自定义聚合函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "16f66aa9-9396-4bd1-a257-6a0a3ebd6a29",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "自定义聚合统计：\n",
      "          数值范围     前3名平均\n",
      "商品类别                    \n",
      "图书      722.35    734.50\n",
      "学习用品    240.84    243.42\n",
      "服装     1462.95   1477.68\n",
      "生活用品    974.05    979.92\n",
      "电子产品  24768.67  24630.33\n",
      "运动器材   2415.35   2443.15\n",
      "食品      488.10    497.83\n",
      "自定义聚合统计：\n",
      "          数值范围     前3名平均\n",
      "商品类别                    \n",
      "图书      722.35    734.50\n",
      "学习用品    240.84    243.42\n",
      "服装     1462.95   1477.68\n",
      "生活用品    974.05    979.92\n",
      "电子产品  24768.67  24630.33\n",
      "运动器材   2415.35   2443.15\n",
      "食品      488.10    497.83\n"
     ]
    }
   ],
   "source": [
    "# 定义自定义聚合函数（实现 Excel 中难以完成的复杂计算）\n",
    "def value_range(x):\n",
    "    \"\"\"计算数值范围\"\"\"\n",
    "    return x.max() - x.min()  \n",
    "    # 计算传入数据的最大值与最小值之差，得到数值范围\n",
    "\n",
    "def top_3_mean(x):\n",
    "    \"\"\"计算前3名的平均值\"\"\"\n",
    "    return x.nlargest(3).mean()  \n",
    "    # 取数据中最大的3个值并计算它们的平均值\n",
    "\n",
    "# 使用自定义函数进行分组统计\n",
    "custom_agg = df_orders.groupby('商品类别')['订单金额'].agg([\n",
    "    ('数值范围', value_range),  # 使用自定义函数 value_range 计算数值范围\n",
    "    ('前3名平均', top_3_mean)   # 使用自定义函数 top_3_mean 计算前3名的平均值\n",
    "]).round(2)  # 将结果保留到小数点后两位\n",
    "\n",
    "print(\"自定义聚合统计：\")\n",
    "print(custom_agg)\n",
    "print(\"自定义聚合统计：\")  \n",
    "# 输出自定义聚合统计的标题\n",
    "\n",
    "print(custom_agg)  \n",
    "# 打印自定义聚合统计的结果"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d4f8cfd7-eb1b-41da-ac6a-f22c2bae9521",
   "metadata": {},
   "source": [
    "多个聚合函数同时使用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "ac219dc2-4562-4848-beef-5afe47620f27",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "综合统计分析：\n",
      "              订单金额                                   购买数量      \n",
      "                总额       均值   数量        范围      前3均值   总量    均量\n",
      "商品类别 年级                                                        \n",
      "图书   大一   28058.13   235.78  119    697.60    671.57  333  2.80\n",
      "     大三   25424.55   242.14  105    703.04    719.60  320  3.05\n",
      "     大二   24642.82   270.80   91    621.91    656.33  274  3.01\n",
      "     大四   33273.54   250.18  133    722.25    704.58  393  2.95\n",
      "学习用品 大一    8780.44    85.25  103    220.91    227.12  316  3.07\n",
      "     大三   11104.98    85.42  130    230.06    235.08  416  3.20\n",
      "     大二    8023.15    79.44  101    236.05    224.27  295  2.92\n",
      "     大四   10896.21    91.56  119    240.84    237.72  362  3.04\n",
      "服装   大一   57876.08   503.27  115   1258.54   1289.10  346  3.01\n",
      "     大三   62729.98   540.78  116   1462.95   1417.68  369  3.18\n",
      "     大二   48709.63   507.39   96   1413.39   1447.63  275  2.86\n",
      "     大四   73158.55   497.68  147   1440.30   1431.25  445  3.03\n",
      "生活用品 大一   31246.15   335.98   93    903.60    914.80  286  3.08\n",
      "     大三   29014.61   315.38   92    896.25    855.42  269  2.92\n",
      "     大二   30295.76   329.30   92    974.05    925.52  289  3.14\n",
      "     大四   49297.13   354.66  139    952.65    965.38  451  3.24\n",
      "电子产品 大一  790696.65  8236.42   96  24054.66  24200.73  278  2.90\n",
      "     大三  673539.79  7089.89   95  24652.67  22164.07  286  3.01\n",
      "     大二  598537.27  6959.74   86  21256.47  19276.43  247  2.87\n",
      "     大四  923251.00  7327.39  126  24052.27  22984.83  393  3.12\n",
      "运动器材 大一   79125.40   791.25  100   2415.35   2403.48  285  2.85\n",
      "     大三   79679.66   838.73   95   2393.44   2362.17  297  3.13\n",
      "     大二   94028.11   895.51  105   2254.50   2280.78  333  3.17\n",
      "     大四   98816.67   778.08  127   2276.33   2283.93  358  2.82\n",
      "食品   大一   15844.35   146.71  108    480.46    440.33  301  2.79\n",
      "     大三   15025.19   159.84   94    482.34    495.62  284  3.02\n",
      "     大二   14793.78   157.38   94    459.95    446.13  289  3.07\n",
      "     大四   16656.84   150.06  111    472.90    458.37  316  2.85\n"
     ]
    }
   ],
   "source": [
    "# 综合分析（相当于 Excel 中多个统计表的组合）\n",
    "comprehensive_analysis = df_orders.groupby(['商品类别', '年级']).agg({\n",
    "    '订单金额': [\n",
    "        ('总额', 'sum'),  # 计算订单金额的总和，并命名为 \"总额\"\n",
    "        ('均值', 'mean'),  # 计算订单金额的平均值，并命名为 \"均值\"\n",
    "        ('数量', 'count'),  # 计算订单数，并命名为 \"数量\"\n",
    "        ('范围', value_range),  # 使用自定义函数计算数值范围，并命名为 \"范围\"\n",
    "        ('前3均值', top_3_mean)  # 使用自定义函数计算前3名的平均值，并命名为 \"前3均值\"\n",
    "    ],\n",
    "    '购买数量': [\n",
    "        ('总量', 'sum'),  # 计算购买数量的总和，并命名为 \"总量\"\n",
    "        ('均量', 'mean')  # 计算购买数量的平均值，并命名为 \"均量\"\n",
    "    ]\n",
    "}).round(2)  \n",
    "# 将所有结果保留到小数点后两位\n",
    "\n",
    "print(\"综合统计分析：\")  \n",
    "# 输出综合统计分析的标题\n",
    "\n",
    "print(comprehensive_analysis)  \n",
    "# 打印综合统计分析的结果"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cf66bd60-8527-40d8-9c1e-37a1729ae4d2",
   "metadata": {},
   "source": [
    "实际应用示例"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "d3655081-dde9-4b34-aac2-15881b7f0f1d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "综合销售分析报表：\n",
      "           订单数        总金额         平均金额      最大订单      平均数量  优惠比例          前3均值\n",
      "商品类别 年级                                                                       \n",
      "图书   大一  119.0   28058.13   235.782605    718.10  2.798319  5.18    671.566667\n",
      "     大三  105.0   25424.55   242.138571    742.55  3.047619  3.93    719.600000\n",
      "     大二   91.0   24642.82   270.800220    665.65  3.010989  4.77    656.333333\n",
      "     大四  133.0   33273.54   250.176992    742.85  2.954887  4.59    704.583333\n",
      "学习用品 大一  103.0    8780.44    85.246990    233.15  3.067961  5.70    227.116667\n",
      "     大三  130.0   11104.98    85.422923    238.90  3.200000  5.96    235.083333\n",
      "     大二  101.0    8023.15    79.437129    244.40  2.920792  5.88    224.266667\n",
      "     大四  119.0   10896.21    91.564790    246.95  3.042017  5.71    237.716667\n",
      "服装   大一  115.0   57876.08   503.270261   1309.10  3.008696  5.62   1289.100000\n",
      "     大三  116.0   62729.98   540.775690   1498.80  3.181034  5.12   1417.683333\n",
      "     大二   96.0   48709.63   507.391979   1453.05  2.864583  5.69   1447.633333\n",
      "     大四  147.0   73158.55   497.677211   1481.20  3.027211  6.23   1431.250000\n",
      "生活用品 大一   93.0   31246.15   335.980108    939.65  3.075269  5.76    914.800000\n",
      "     大三   92.0   29014.61   315.376196    922.80  2.923913  5.72    855.416667\n",
      "     大二   92.0   30295.76   329.301739    994.30  3.141304  4.82    925.516667\n",
      "     大四  139.0   49297.13   354.655612    980.90  3.244604  4.93    965.383333\n",
      "电子产品 大一   96.0  790696.65  8236.423437  24392.15  2.895833  4.75  24200.733333\n",
      "     大三   95.0  673539.79  7089.892526  24901.15  3.010526  3.52  22164.066667\n",
      "     大二   86.0  598537.27  6959.735698  21388.95  2.872093  4.99  19276.430000\n",
      "     大四  126.0  923251.00  7327.388889  24597.70  3.119048  6.26  22984.833333\n",
      "运动器材 大一  100.0   79125.40   791.254000   2465.80  2.850000  5.23   2403.483333\n",
      "     大三   95.0   79679.66   838.733263   2462.60  3.126316  4.69   2362.166667\n",
      "     大二  105.0   94028.11   895.505810   2343.20  3.171429  4.70   2280.783333\n",
      "     大四  127.0   98816.67   778.084016   2377.25  2.818898  6.20   2283.933333\n",
      "食品   大一  108.0   15844.35   146.706944    498.50  2.787037  6.20    440.333333\n",
      "     大三   94.0   15025.19   159.842447    497.85  3.021277  4.50    495.616667\n",
      "     大二   94.0   14793.78   157.380638    477.70  3.074468  4.96    446.133333\n",
      "     大四  111.0   16656.84   150.061622    483.30  2.846847  4.29    458.366667\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\Administrator\\AppData\\Local\\Temp\\ipykernel_20912\\3356690160.py:14: DeprecationWarning: DataFrameGroupBy.apply operated on the grouping columns. This behavior is deprecated, and in a future version of pandas the grouping columns will be excluded from the operation. Either pass `include_groups=False` to exclude the groupings or explicitly select the grouping columns after groupby to silence this warning.\n",
      "  sales_report = df_orders.groupby(['商品类别', '年级'], group_keys=False).apply(sales_analysis)\n"
     ]
    }
   ],
   "source": [
    "def sales_analysis(group):\n",
    "    \"\"\"综合销售分析\"\"\"\n",
    "    return pd.Series({\n",
    "        '订单数': len(group),  # 计算订单数\n",
    "        '总金额': group['订单金额'].sum(),  # 计算总销售金额\n",
    "        '平均金额': group['订单金额'].mean(),  # 计算平均订单金额\n",
    "        '最大订单': group['订单金额'].max(),  # 计算最大订单金额\n",
    "        '平均数量': group['购买数量'].mean(),  # 计算平均购买数量\n",
    "        '优惠比例': (group['优惠金额'].sum() / group['订单金额'].sum() * 100).round(2),  # 计算优惠金额占订单金额的百分比\n",
    "        '前3均值': group['订单金额'].nlargest(3).mean()  # 计算订单金额中最大的3个值的平均\n",
    "    })\n",
    "\n",
    "# 使用 apply 进行分组计算，并排除分组列\n",
    "sales_report = df_orders.groupby(['商品类别', '年级'], group_keys=False).apply(sales_analysis)\n",
    "\n",
    "print(\"综合销售分析报表：\")\n",
    "print(sales_report)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bd776466-c241-49a4-bf1d-6d6096ea0bbd",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
